package com.qingfeng.client.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.qingfeng.base.exception.LsException;
import com.qingfeng.base.model.Page;
import com.qingfeng.base.util.CodeEnum;
import com.qingfeng.client.DO.GoodsInfoDo;
import com.qingfeng.client.VO.GoodsQueryVo;
import com.qingfeng.client.bean.Goods;
import com.qingfeng.client.bean.Goods2attrs;
import com.qingfeng.client.bean.GoodsCommon;
import com.qingfeng.client.bean.GoodsUpdateVo;
import com.qingfeng.client.dao.AttrValueMapper;
import com.qingfeng.client.dao.Goods2attrsMapper;
import com.qingfeng.client.dao.GoodsCommonMapper;
import com.qingfeng.client.dao.GoodsMapper;
import com.qingfeng.client.util.MakeOrderNum;
import com.qingfeng.client.util.RandomUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 商品，每种属性都便是一个商品
 * 1.增删改查
 * 查：销量，评论，价格
 * 2.获取商品品牌列表
 * 3.获取商品属性列表
 *
 * @Author ff
 * @Data 2017/10/25 13:27
 */
@Service
public class GoodsService {

    @Resource
    private GoodsCommonMapper goodsCommonDao;

    @Resource
    private GoodsMapper goodsDao;

    @Resource
    private Goods2attrsMapper goods2AttrsDao;

    @Resource
    private AttrValueMapper attrValueMapper;

    /**
     * 1. 修改通用属性
     * 2。修改商品属性vualeId对应的value值，如果无valueId 则添加valueId
     * 3。如果商品有商品id则修改商品属性，如果没有id则添加商品，并且添加属性
     * @param vo
     */
    @Transactional
    public void update(GoodsUpdateVo vo){
        //修改商品基本属性,GoodsCommon里面的基本属性:商品名称...
        updateGoodsCommon(vo.getGoodsCommon());

        // 更新已有的属性,Goods2attrsBean,无则添加临时变量
        updateValueByValueId(vo.getUpdateAttrs());

        List<Goods> goods = vo.getGoods();

        for (Goods item:goods){
            if (item.getId()!=null){
                goodsDao.updateById(item);
            }else {
                //需要新增的商品
                goodsDao.insert(item);
                for (Goods2attrs goods2attrs:item.getGoods2attrsBeans()){
                    Integer valueId = getValueId(goods2attrs,vo.getUpdateAttrs());
                    if (valueId==null){
                        throw new LsException(CodeEnum.UNKNOWN_ERROR.getCode(),"valueId 生成失败");
                    }
                    goods2attrs.setValueId(valueId);
                    goods2attrs.setGoodsId(item.getId());
                    goods2AttrsDao.insert(goods2attrs);
                }
            }
        }

    }

    /**
     * 如果valueId 不为空则直接返回，
     * 如果valueId 为空，则在list中寻在有相同 attrId和相同value值的对象，并返回valueId
     * @param goods2attrs
     * @param list
     * @return
     */
    private Integer getValueId(Goods2attrs goods2attrs,List<Goods2attrs> list){
        if (goods2attrs.getValueId()!=null){
            return goods2attrs.getValueId();
        }else {
            for(Goods2attrs item:list){
                if (goods2attrs.getAttrsId().equals(item.getAttrsId())
                && goods2attrs.getValue().equals(item.getValue())){
                    return item.getValueId();
                }
            }
        }
        return null;
    }




    private void addAttrs(List<Goods> goodsBeans) {
        List<Goods2attrs> list = new ArrayList<>();
        Integer maxValueId = goods2AttrsDao.getMaxValueId();
        if (maxValueId == null) {
            maxValueId = 1;
        }
        HashMap<String, Integer> valueMap = new HashMap<>();
        for (Goods goods : goodsBeans) {
            Long id = goods.getId();
            List<Goods2attrs> goods2attrsBeans = goods.getGoods2attrsBeans();
            for (int i = 0; i < goods2attrsBeans.size(); i++) {
                Goods2attrs goods2attrs = goods2attrsBeans.get(i);
                String value = goods2attrs.getValue();
                Integer valueId = MapUtils.getInteger(valueMap, value);
                if (valueId == null) {
                    maxValueId += 1;
                    valueId = maxValueId;
                    valueMap.put(value, valueId);
                }
                goods2attrs.setValueId(valueId);
                goods2attrs.setGoodsId(goods.getId());
                list.add(goods2attrs);
            }
        }
        goods2AttrsDao.insertList(list);
    }

    /**
     * 增加商品,增加物品，和其对应的属性
     *
     * @param goodsCommon
     * @return
     */
    @Transactional
    public boolean add(final GoodsCommon goodsCommon, List<Goods> goodsBeans) {
        goodsCommon.setRecommend(0);
        int now = (int) (System.currentTimeMillis()/1000);
        goodsCommon.setCreateTime(now);
        goodsCommon.setUpdateTime(now);
        goodsCommonDao.insert(goodsCommon);
        for (Goods goods : goodsBeans) {
            goods.setGoodsCommonId(goodsCommon.getId());
            goods.setCreateTime((int) (System.currentTimeMillis() / 1000));
            goods.setGoodsCode(MakeOrderNum.getOrderNum());
            goods.setState(1);
            goodsDao.insert(goods);
        }
        addAttrs(goodsBeans);
        return true;

    }


    /**
     * 更改多个商品的，品牌，类型，价格，活动，名称，库存，详情，属性值
     *
     * @return
     */
    @Transactional
    public boolean updateGoods(List<Goods> goodsBeans) {
        int result = 0;
        for (Goods goodsBean : goodsBeans) {
            result = goodsDao.updateById(goodsBean);
            if (result < 0) {
                throw new LsException(0, "update failed:" + goodsBean.toString());
            }
        }
        return true;
    }


    /**
     * 分页查询店铺中的商品，
     *
     * @param goodsQueryVo
     * @return
     */
    public IPage<GoodsInfoDo> queryByStore(Page page, GoodsQueryVo goodsQueryVo) {
        return goodsDao.queryByStore(page, goodsQueryVo);
    }

    /**
     * 查询店铺中的所有商品，
     *
     * @param goodsQueryVo
     * @return
     */
    public List<GoodsCommon> queryAllByStore(GoodsQueryVo goodsQueryVo) {
        return goodsDao.queryAllByStore(goodsQueryVo);
    }


    /**
     * 获取一个商品的所有详细属性
     *
     * @param id
     * @return
     */
    public List getGoodsInfo(Long id) {
        List<Map<String, Object>> goodsBeans = goodsDao.getGoods(id);
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        Map<String, Object> currentGoodsBean = null;
        List<Goods2attrs> attrsBeans = new ArrayList<>();
        long currentId = -1L;
        for (Map<String, Object> map : goodsBeans) {
            long goodsId = MapUtils.getLong(map, "goods_id");

            if (currentId != goodsId) {
                if (currentGoodsBean != null) {
                    currentGoodsBean.put("goods2attrsBeans", attrsBeans);
                    list.add(currentGoodsBean);
                    attrsBeans = new ArrayList<>();
                }
                currentId = goodsId;
                currentGoodsBean = new HashMap<>();
                currentGoodsBean.put("id", goodsId);
                currentGoodsBean.put("goodsCommonId", MapUtils.getLong(map, "goods_common_id"));
                currentGoodsBean.put("procurementPrice", MapUtils.getLong(map, "procurement_price"));
                currentGoodsBean.put("price", MapUtils.getLong(map, "price"));
                currentGoodsBean.put("size", MapUtils.getLong(map, "size"));
                currentGoodsBean.put("canSellSize", MapUtils.getLong(map, "can_sell_size"));
                currentGoodsBean.put("sellSize", MapUtils.getLong(map, "sell_size"));
                currentGoodsBean.put("createTime", MapUtils.getLong(map, "create_time"));
                currentGoodsBean.put("goodsCode", MapUtils.getString(map, "goods_code"));
                currentGoodsBean.put("changeTime", MapUtils.getLong(map, "change_time"));
                currentGoodsBean.put("state",MapUtils.getIntValue(map,"state"));
                currentGoodsBean.put("weight",MapUtils.getIntValue(map,"weight"));
            }
            Goods2attrs goods2attrsBean = new Goods2attrs();
            goods2attrsBean.setGoodsId(MapUtils.getLong(map, "goods_id"));
            goods2attrsBean.setAttrsId(MapUtils.getInteger(map, "attrs_id"));
            goods2attrsBean.setAttrsName(MapUtils.getString(map, "name"));
//            goods2attrsBean.setState(MapUtils.getLong(map, "state"));
            goods2attrsBean.setValue(MapUtils.getString(map, "value"));
            goods2attrsBean.setValueId(MapUtils.getInteger(map, "value_id"));
            goods2attrsBean.setGoodsCommonId(MapUtils.getLong(map,"goods_common_id"));
            attrsBeans.add(goods2attrsBean);
            currentGoodsBean.put("attr_" + goods2attrsBean.getAttrsId(), goods2attrsBean.getValue());
        }
        currentGoodsBean.put("goods2attrsBeans", attrsBeans);
        list.add(currentGoodsBean);
        return list;
    }



    @Transactional
    public boolean updateGoodsCommon(GoodsCommon goodsCommonBean) {
        goodsCommonBean.setUpdateTime((int) System.currentTimeMillis());
        goodsCommonDao.updateById(goodsCommonBean);
        return true;
    }

    public void updateValueByValueId(List<Goods2attrs> updateAttrs) {
        for (Goods2attrs goods2attrs : updateAttrs) {
            if (goods2attrs.getValueId()!=null){
                goods2AttrsDao.updateValueByGoodsCommonIdAndAttrsIdAndValueId(goods2attrs.getValue(),
                        goods2attrs.getGoodsCommonId(),goods2attrs.getAttrsId(),goods2attrs.getValueId());
            }else {
                //用秒级别d时间戳作为valueId
                Integer valueId = goods2AttrsDao.getMaxValueId();
                if (valueId==null){
                    valueId=0;
                }else {
                    valueId++;
                }
                goods2attrs.setValueId(valueId);
            }
        }
    }

    public void updateGoods2(List<Goods> goods, Long goodsCommonId) {
        List<Goods> needAdd = new ArrayList<>();
        List<Goods> needUpdate = new ArrayList<>();
        for (Goods goodsBean : goods) {
            //goods中新增商品，填入goodsCommonId和state
            if (goodsBean.getId() == null) {
                goodsBean.setState(1);
                needAdd.add(goodsBean);
            } else {
                needUpdate.add(goodsBean);
            }
        }
        //修改已存在商品
        updateGoods(needUpdate);
        //needAdd新增商品和已有valueId的属性
        addGoods2(needAdd,goodsCommonId);
        //needAddAttr新增属性
        inserts(goods);
    }

    //添加新增的商品和其已有属性valueId值的attr
    private void addGoods2(List<Goods> needAdd,Long goodsCommonId) {
        List<Goods2attrs> listAttr = new ArrayList<>();
        for (Goods goodsBean : needAdd) {
            if (goodsBean.getCreateTime() == null) {
                goodsBean.setCreateTime((int) (System.currentTimeMillis() / 1000));
                goodsBean.setUpdateTime(goodsBean.getCreateTime());
//                Long lastId=getLastId();
                goodsBean.setState(1);
                goodsBean.setGoodsCommonId(goodsCommonId);
                String goodsCode = RandomUtil.getRandomString(14, System.currentTimeMillis() + 1) + 1;
                goodsBean.setGoodsCode(goodsCode);
            }
            goodsDao.insert(goodsBean);
            List<Goods2attrs> list = goodsBean.getGoods2attrsBeans();
            for (Goods2attrs goods2attrsBean : list) {
                if (goods2attrsBean.getValueId() != null) {
                    goods2attrsBean.setGoodsId(goodsBean.getId());
                    listAttr.add(goods2attrsBean);
                }
            }
        }
        if (listAttr.size() > 0) {
            goods2AttrsDao.insertList(listAttr);
        }
    }

    public List fanXian(Long id) {
        return goodsDao.fanXian(id);
    }

    public boolean updateState(JSONObject jsonObject) {
        int goodsId = jsonObject.getIntValue("goodsId");
        int state = jsonObject.getIntValue("state");
        Goods goods = new Goods();
        UpdateWrapper<Goods> wrapper = new UpdateWrapper<>();
        wrapper.set("state", state).eq("id", goodsId);

        int flag = this.goodsDao.update(goods, wrapper);
        if (flag == 0) {
            return false;
        }
        return true;
    }


    /**
     * @param goodsBeans
     * 添加商品属性
     */
    public boolean inserts(List<Goods> goodsBeans) {
        List<Goods2attrs> list = new ArrayList<>();
        int maxValueId = getMaxValueId();
        HashMap<String,Integer> valueMap = new HashMap<>();
        for (Goods goods:goodsBeans){
            List<Goods2attrs> attrs = goods.getGoods2attrsBeans();
            for (Goods2attrs goods2attrs:attrs){
                Integer valueId = goods2attrs.getValueId();
                if (valueId!=null){
                    continue;
                }else {
                    String value = goods2attrs.getValue();
                    Integer nowValueId = MapUtils.getInteger(valueMap,value);
                    if (nowValueId==null){
                        nowValueId = maxValueId;
                        maxValueId++;
                        valueMap.put(value,nowValueId);
                    }
                    goods2attrs.setGoodsId(goods.getId());
                    goods2attrs.setValueId(nowValueId);
                    list.add(goods2attrs);
                }
            }
        }
        if(!CollectionUtils.isEmpty(list)){
            if (goods2AttrsDao.inserts(list)) {
                return true;
            } else {
                return false;
            }
        }
        return true;
    }

    public int getMaxValueId() {
        Integer maxValueId1 = goods2AttrsDao.getMaxValueId();
//        int maxValueId = (int) (maxValueId1+1);
        if (maxValueId1 == null) {
            return 0;
        } else {
            return (int) (maxValueId1 + 1);
        }
    }

    public int getCategory(Long id) {
        return goodsCommonDao.getTypeid(id);
    }
}
